package com.rzjm.exercise.common.base.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rzjm.exercise.common.base.dao.BaseDao;
import com.rzjm.exercise.common.base.data.DataTable;
import com.rzjm.exercise.common.base.data.DataTableLayUI;
import com.rzjm.exercise.common.base.data.SearchCondition;
import com.rzjm.exercise.common.base.service.BaseService;
import com.rzjm.exercise.common.constant.SearchParam;

import com.rzjm.exercise.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.locks.Condition;

@SuppressWarnings("unchecked")
public abstract class BaseServiceImpl<M extends BaseDao<T>, T> extends ServiceImpl<M, T> implements BaseService<T> {

    protected Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    protected M baseDao;

    @Override
    public T findById(Serializable id) {
        return getById(id);
    }

    /**
     * 根据map参数查询数量
     *
     * @param params
     * @return
     */
    @Override
    public long selectCountByMap(Map<String, Object> params) {
        return baseDao.selectCountByMap(params);
    }

    /**
     * 根据QueryWrapper参数查询数量
     *
     * @param qw
     * @return
     */
    @Override
    public long selectCountByQueryWrapper(QueryWrapper<T> qw) {
        return baseDao.selectCountByQueryWrapper(qw);
    }


    /**
     * 根据一列值查询数量
     * @param column
     * @param value
     * @return
     */
    @Override
    public long selectCountByColumn(String column, Object value) {
        return baseDao.selectCountByColumn(column, value);
    }

    /**
     * 通过一列值查询
     *
     * @return
     */
    @Override
    public List<T> selectByMap(Map<String, Object> params){
        return baseDao.selectByMap(params);
    }

    /**
     * 通过一列值查询
     *
     * @param column
     * @param value
     * @return
     */
    @Override
    public List<T> selectListByColumn(String column, Object value) {
        return baseDao.selectListByColumn(column, value);
    }


    public List<T> selectListByQueryWrapper(QueryWrapper<T> qw){
        return baseDao.selectListByQueryWrapper(qw);
    }

    /**
     * 通过一唯一列值查询唯一值
     *
     * @param column
     * @param value
     * @return
     */
    @Override
    public T selectByUniqueColumn(String column, Object value) {
        QueryWrapper<T> qw = new QueryWrapper<T>();
        qw.eq(column,value);
        qw.last("limit 1");
        return baseDao.selectOne(qw);
    }

    /**
     * 查询表上所有数据
     *
     * @return
     */
    @Override
    public List<T> selectAllList() {
        return baseDao.selectAllList();
    }

    /**
     * 是否加载 查询条件
     *
     * @param cnd
     * @param k
     * @param v
     * @return
     */
    private boolean idLoadCnd(String cnd, String k, Object v) {
        return k.startsWith(cnd) && null != v && v.toString().length() > 0;
    }

    /**
     * 加载 搜索条件
     *
     * @param searchParams
     * @param qw
     */
    private void loadSearchParam(Map<String, Object> searchParams, QueryWrapper qw) {
        if (null != searchParams) {
            searchParams.forEach((k, v) -> {
                if (idLoadCnd(SearchParam.SEARCH_EQ, k, v)) {
                    qw.eq(underscoreName(k.split(SearchParam.SEARCH_EQ)[1]), v);
                } else if (idLoadCnd(SearchParam.SEARCH_LLIKE, k, v)) {
                    qw.likeLeft(underscoreName(k.split(SearchParam.SEARCH_LLIKE)[1]),String.valueOf(v));
                } else if (idLoadCnd(SearchParam.SEARCH_RLIKE, k, v)) {
                    qw.likeRight(underscoreName(k.split(SearchParam.SEARCH_RLIKE)[1]), String.valueOf(v));
                } else if (idLoadCnd(SearchParam.SEARCH_LIKE, k, v)) {
                    qw.like(underscoreName(k.split(SearchParam.SEARCH_LIKE)[1]), String.valueOf(v));
                } else if (idLoadCnd(SearchParam.SEARCH_GE, k, v)) {//大于等于
                    qw.ge(underscoreName(k.split(SearchParam.SEARCH_GE)[1]), String.valueOf(v));
                } else if (idLoadCnd(SearchParam.SEARCH_GT, k, v)) {//大于
                    qw.gt(underscoreName(k.split(SearchParam.SEARCH_GT)[1]), String.valueOf(v));
                } else if (idLoadCnd(SearchParam.SEARCH_LE, k, v)) {//小于等于
                    String ss = underscoreName(k.split(SearchParam.SEARCH_LE)[1]);
                    System.out.println("ss:" + ss);
                    String vv = String.valueOf(v);
                    System.out.println("vv:" + vv);
                    qw.le(ss, String.valueOf(v));
                } else if (idLoadCnd(SearchParam.SEARCH_LT, k, v)) {//小于
                    qw.lt(underscoreName(k.split(SearchParam.SEARCH_LT)[1]), String.valueOf(v));
                }

            });
        }
    }

    /**
     * 加载 排序条件
     */
    private void loadSort(Map<String, String> sorts, QueryWrapper qw) {
        if (null != sorts && sorts.size() > 0) {
            StringBuffer stringBuffer = new StringBuffer();
            sorts.forEach((k, v) -> {
//                stringBuffer.append(k);
//                stringBuffer.append("asc".equals(v.toLowerCase()) ? " ASC ," : " DESC ,");
                if("asc".equals(v.toLowerCase())){
                    qw.orderByAsc(k);
                }else{
                    qw.orderByDesc(k);
                }
            });
//            String str = stringBuffer.toString().trim().substring(0, stringBuffer.length() - 1);
        }
    }

    protected String underscoreName(String name) {
		if (!StringUtils.hasLength(name)) {
			return "";
		}
		StringBuilder result = new StringBuilder();
		result.append(lowerCaseName(name.substring(0, 1)));
		for (int i = 1; i < name.length(); i++) {
			String s = name.substring(i, i + 1);
			String slc = lowerCaseName(s);
			if (!s.equals(slc)) {
				result.append("_").append(slc);
			} else {
				result.append(s);
			}
		}
		return result.toString();
	}

	protected String lowerCaseName(String name) {
		return name.toLowerCase(Locale.US);
	}



	private void loadWrapper(QueryWrapper wrapper, Condition cnd){
        if(wrapper!=null){
        }
    }

    /**
     * 分页 搜索
     *
     * @param condition
     * @return
     */
	@Override
	public DataTable<T> pageSearch(DataTable<T> condition) {
        Page<T> page = new Page<T>(condition.getPageNumber(), condition.getPageSize());
        SearchCondition cnd = SearchCondition.create();
        loadSearchParam(condition.getSearchParams(), cnd);
        loadSort(condition.getSorts(), cnd);
        page(page, cnd);
        condition.setTotal(page.getTotal());
        condition.setRows(page.getRecords());
        condition.setTotalPages(page.getPages());
        return condition;
    }
    /**
     * 分页 搜索
     *
     * @param condition
     * @return
     */
    @Override
    public DataTableLayUI<T> pageSearchLayUI(DataTableLayUI<T> condition) {
        Page<T> page = new Page<T>(condition.getPage(), condition.getLimit());
        SearchCondition cnd = SearchCondition.create();
        if(condition.getQw()!=null){
            loadSort(condition.getSorts(), condition.getQw());
            page(page, condition.getQw());
        }else{
            loadSearchParam(condition.getSearchParams(), cnd);
            loadSort(condition.getSorts(), cnd);
            page(page, cnd);
        }
        condition.setCount(page.getTotal());
        condition.setData(page.getRecords());
        condition.setTotalPages(page.getPages());
        condition.setCode(0);
        condition.setMsg("success");
        return condition;
    }


    /**
     * 分页 搜索
     *
     * @param condition
     * @return
     */
    @Override
    public DataTableLayUI<T> pageSearchCustom(Page<T> page,List<T> list, DataTableLayUI<T> condition) {
        condition.setCount(page.getTotal());
        condition.setData(list);
        condition.setTotalPages(page.getPages());
        condition.setCode(0);
        condition.setMsg("success");
        return condition;
    }

    @Override
    public List<T> selectOptionsList(String params) {
        return null;
    }

    @Override
    public List<T> selectOptionsList() {
        return null;
    }

    @Override
    public Page<T> getPage(DataTableLayUI<T> condition) {
        Page<T> page = new Page<T>(condition.getPage(), condition.getLimit());
        return page;
    }
}
